//
//  rootViewController.swift
//  YoruNeko
//
//  Created by hgc on 2021/6/15.
//

import Foundation
import UIKit
import SwiftUI

class YoruNekoViewController: UINavigationController{

    //管理childView
    
    var tabViewController: TabViewController!
    let tabViewModelData = TabItemsModelData()
    var tabSwitchViewControllerPointer: YRNKHostingControllerPointer?
    var currentVCPointer: YRNKHostingControllerPointer?
//    var cachedImageViewer: YRNKHostingControllerPointer?
    
    class CachedImageViewerInfo{
        static var instance: CachedImageViewerInfo = CachedImageViewerInfo()
        var cachedImageViewer: YRNKHostingControllerPointer?
        var cachedImgUrls: [ImageInfo]?
        var cachedModelData: ImageViewModelData?
        private init(){
        }
        static func getInstance()->CachedImageViewerInfo{
            return instance
        }
    }
    
    init(){
        start = Date.init()
        super.init(nibName: nil, bundle: nil)
        tabViewController = TabViewController.init(_parent: self)
        YRNKSharedThreadPool.dispatchTask(operation: {
            do {
                let _ = try HistoryManager.readHistoryList(of: UserManager.currUserUuid)
            } catch {
                YRNKLog(self.description, msg: error.localizedDescription)
            }
        })
        YRNKSharedThreadPool.dispatchTask(operation: {
            do{
                let _ = try BookmarkManager.readBookmarkList(of: UserManager.currUserUuid)
            }catch {
                YRNKLog(self.description, msg: error.localizedDescription)
                //YRNKLog(self.description, msg: error)
            }

        }, priority: .HIGH)

        self.navigationBar.isHidden = true
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    // 禁止自动旋转
    override var shouldAutorotate : Bool {
        return false
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        print("====================================")
        NSLog("%s call viewDidLoad", self.description)
        
        //load childView
        tabViewController.setParentController(parentVC: self)
        tabViewController.setModelData(modelData: tabViewModelData)
        self.addChild(tabViewController)
        view.addSubview(tabViewController.view)
        tabViewController.didMove(toParent: self)
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(true)
    }
    
    override func viewDidDisappear(_ animated: Bool) {
        NSLog("%s call viewDidDisapper", self.description)
        print("====================================")
    }
    
    //用于管理subView
    func showSubView(_ hostingControllerPointer: YRNKHostingControllerPointer){
//        vc.modalPresentationStyle = UIModalPresentationStyle.fullScreen
//        let transition = CATransition()
//        transition.duration = 0.5
//        transition.type = CATransitionType.push
//        transition.subtype = CATransitionSubtype.fromLeft
//        transition.timingFunction = CAMediaTimingFunction(name:CAMediaTimingFunctionName.easeInEaseOut)
//        view.window!.layer.add(transition, forKey: kCATransition)
//        present(vc, animated: false, completion: nil)
//        presentedVC = vc
        //vc.modalTransitionStyle = .coverVertical
        currentVCPointer = hostingControllerPointer
        if hostingControllerPointer.getViewType()==ViewType.SearchView{
            hostingControllerPointer.getViewController().modalPresentationStyle = UIModalPresentationStyle.fullScreen
            self.present(hostingControllerPointer.getViewController(), animated: true, completion: nil)
            //self.present(hostingControllerPointer.getViewController(), animated: true, completion: nil)
        }else{
            let vc = hostingControllerPointer.getViewController()
            self.pushViewController(vc, animated: true)
        }
        //self.show(vc, sender: self)
    }
    
    func dismissCurrentView(animated: Bool){
        //        let transition = CATransition()
        //        transition.duration = 0.5
        //                    transition.type = CATransitionType.push
        //                    transition.subtype = CATransitionSubtype.fromRight
        //                    transition.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
        //                    self.view.window?.layer.add(transition, forKey: kCATransition)
                //self.dismiss(animated: false, completion: nil)
        if currentVCPointer?.getViewType()==ViewType.SearchView{
            currentVCPointer?.getViewController().dismiss(animated: true, completion: nil)
        }else{
            self.popViewController(animated: animated)
        }
    }

}
extension YoruNekoViewController: ViewCallBack{
    //退出当前页面
    func goBack(){
        //若只剩0条记录，则直接新增页面
        if tabViewController.getCurrentViewCount() == 0 {
            let _ = tabViewController.addIndexView()
        }
        print("rootViewController: goBack called")
//        let transition = CATransition()
//                    transition.duration = 0.5
//                    transition.type = CATransitionType.push
//                    transition.subtype = CATransitionSubtype.fromLeft
//                    transition.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
//                    presentedVC?.view.window!.layer.add(transition, forKey: kCATransition)
        //self.dismiss(animated: false, completion: nil)
        dismissCurrentView(animated: true)
    }
    
    func goToView(to viewIdentifier:ViewType,from senderViewType:ViewType,intent:YRNKIntent,with requestArgument:[RequestArgumentKey:Any]?){
        let newVC: UIViewController
        NSLog("%s gotoView method called", self.description)
        dismissCurrentView(animated: true)
        switch viewIdentifier {
        case .ImageViewer:
            if  senderViewType == .IndexView && intent == .Default {
                guard let req_arg = requestArgument else{
                    break
                }
                guard let imgUrls = req_arg[.imageUrls] as? [ImageInfo] else{
                    break
                }
                guard let index = req_arg[.index] as? Int else{
                    break
                }
                
                /*
                 TODO: 服用ImageViewer ,如果接收到的imageUrls集合内容没有发生变化，则复用上一次创建的ImageViewer
                 */

                if CachedImageViewerInfo.getInstance().cachedImgUrls != imgUrls {
                    let modelData = ImageViewModelData.init(with: index)
                    CachedImageViewerInfo.getInstance().cachedModelData = modelData
                    let view = ImageViewer.init(callback: self,  imageUrls: imgUrls).environmentObject(modelData)
                    let realView = view
                    newVC = UIHostingController(rootView: realView)
                    let wrappedHostingController = YRNKHostingController.init(rootView: view, vc: newVC)
                    CachedImageViewerInfo.getInstance().cachedImageViewer = wrappedHostingController
                    CachedImageViewerInfo.getInstance().cachedImgUrls = imgUrls
                }
                if let cImageViewer = CachedImageViewerInfo.getInstance().cachedImageViewer{
                    CachedImageViewerInfo.getInstance().cachedModelData?.index = index
                    showSubView(cImageViewer)
                }

                break
            }
        case .SettingView:
            let view = SettingView(callback: self)
            let realView = view
            newVC = UIHostingController(rootView: realView)
            let wrappedHostingController = YRNKHostingController.init(rootView: view, vc: newVC)
            showSubView(wrappedHostingController)
            break
        case .IndexView:
            if intent == .openNewTabOnIndexView {
                //TODO: 判断是否有传入参数
               /*
                 ISSUE:
                 这里会出现空指针错误，如果IndexView并未加载webView
                 */
                if let req_arg = requestArgument{
                    if let wd = req_arg[.wd] as? String {
                        let uuid = tabViewController.addIndexView(toLoadWD: wd)
                        tabViewController.changeView(uuid: uuid)
                    }
                }
                else{
                    tabViewController.changeView(uuid: tabViewController.addIndexView())
                }
            }
            if intent == .Default{
                guard let req_arg = requestArgument else{
                    break
                }
                if let url = req_arg[.url] as? String{
                tabViewController.changeCurrentUrl(url: url)
                }
                if let wd = req_arg[.wd] as? String{
                tabViewController.changeCurrentUrl(url: wd)
                }
                if let id = req_arg[.id] as? UUID{
                    tabViewController.changeView(uuid: id)
                }
            }
            print(self.description+"changeTo indexView")
            break
        case .HistoryView:
            let view = BrowseHistoryView(callback: self)
            let realView = view
            newVC = UIHostingController(rootView: realView)
            let wrappedHostingController = YRNKHostingController.init(rootView: view, vc: newVC)
            showSubView(wrappedHostingController)
            break
        case .DownloadView:
            let view = DownloadView(callback: self)
            let realView = view.environmentObject(DownloadViewModelData.init(with: [DownloadViewItem.init("title", urlStr: "url", contentLength: 10)]))
            newVC = UIHostingController(rootView: realView)
            let wrappedHostingController = YRNKHostingController.init(rootView: view, vc: newVC)
            showSubView(wrappedHostingController)
            break
        case .BookmarkView:
            let view = BookmarkView(callback: self)
            let realView = view.environmentObject(BookmarkData())
            newVC = UIHostingController(rootView: realView)
            let wrappedHostingController = YRNKHostingController.init(rootView: view, vc: newVC)
            showSubView(wrappedHostingController)
            break
        case .SearchView:
            if senderViewType == .SettingView {
                break
            }
            if senderViewType == .IndexView{
                guard let req_arg = requestArgument else{
                    break
                }
                guard let title = req_arg[.title] as? String else{
                    break
                }
                guard let url = req_arg[.url] as? String else{
                    break
                }
                let view = SearchView(currentPageUrl: url, currentPageTitle: title,  callBack: self)
                let realView = view.environmentObject(HistoryListModelData())
                newVC = UIHostingController(rootView: realView)
                let wrappedHostingController = YRNKHostingController.init(rootView: view, vc: newVC)
                showSubView(wrappedHostingController)
            }
            break
        case .TabSwitchView:
            if tabSwitchViewControllerPointer == nil{
                let view = TabSwitchView(callback: self)
                let realView = view.environmentObject(tabViewModelData)
                newVC = UIHostingController(rootView: realView)
                let wrappedHostingController = YRNKHostingController.init(rootView: view, vc: newVC)
                
                tabSwitchViewControllerPointer = wrappedHostingController
            }
            showSubView(tabSwitchViewControllerPointer!)
            break
        default:
            break
        

        }
    }
    

}

extension YoruNekoViewController: IndexCallback{
    
    func getTabCount() -> Int {
        return tabViewModelData.TabItemList.count
    }
    
    func setTabItemAttribute(id:UUID, title: String?, urlStr: String, logo: UIImage?, snapshot: UIImage?) {
        if let index = tabViewModelData.TabItemList.firstIndex(where: {$0.id == id}){
            tabViewModelData.TabItemList[index].url = urlStr
            if let temp = title {tabViewModelData.TabItemList[index].title = temp}
            if let temp = logo {tabViewModelData.TabItemList[index].logo = Image(uiImage: temp)}
            if let temp = snapshot {tabViewModelData.TabItemList[index].image = Image(uiImage: temp)}
        }
    }
    
    func changeCurrentUser(id: String){
        do{
            let result = try HistoryManager.saveHistoryList()
            if(!result){
                YRNKLog(self.description, msg: "saveHistoryList error")
            }
        }catch{
            
        }
        UserManager.setCurrUser(uuidString: id)
        HistoryManager.refresh()
        tabViewController.removeAllView()
        let _ = tabViewController.addIndexView()
    }
    
    /*
     添加书签
     */
    func addBookmark(title:String?,urlStr:String,faviconData:Data?,toBookmarkParentUuid: UUID?){
        let date = Date()
        let tempBookmark = Bookmark(date_added: date, last_visited: date, name: title ?? "", url: urlStr, img: faviconData)
        let tempYRNKBookmark = YRNKBookmark(reference: tempBookmark, parent: BookmarkManager.findItemByUuid(uuid: toBookmarkParentUuid ?? BookmarkManager.getCachedBookmarkRoot().this.id), isDirectory: false)
        BookmarkManager.addBookmark(parentUuid: toBookmarkParentUuid ?? BookmarkManager.getCachedBookmarkRoot().this.id, childPoint: tempYRNKBookmark)
    }
    
    func deleteBookmark(urlStr: String) -> Bool {
        if let uuid = BookmarkManager.findUuidByUrl(url: urlStr) {
            return BookmarkManager.deleteBookmark(uuid: uuid)
        }else{
            return false
        }
    }
    
    func isBookmarked(url: String) -> Bool{
        return BookmarkManager.isUrlExist(url: url)
    }
}

extension YoruNekoViewController: DownloadViewCallBack{
    
    func deleteDownloadItemById(id:Int){
        
    }
    func pauseDownloadById(id:Int){
        
    }
    func resumeDownloadById(id:Int){
        
    }
    func createDownload(downloadUrl:URL,fileName:String)->DownloadViewItem{
        return DownloadViewItem("title", urlStr: "url", contentLength: 10)
    }
    
    func openFile(item_id_hashValue:Int){
        
    }
    
}
extension YoruNekoViewController: TabSwitchCallBack{
    // 请求创建新的标签页
    func createNewTabView(){
        //self.goToView(by: .IndexView, sender: nil, with: nil)
        self.goToView(to: .IndexView, from: .TabSwitchView, intent: .openNewTabOnIndexView, with: nil)
        //self.goBack()
    }
    // 通过id删除某个标签页
    func deleteTabViewById(id: UUID){

        let _ = tabViewController.removeViewById(uuid: id)

    }
    // 删除所有标签页
    func deleteAllTabViews(){
        tabViewController.removeAllView()
        let _ = tabViewController.addIndexView()
        self.goBack()
    }
    // 通过id跳转到某个标签页
    func jumpTo(by uuid: UUID){
        tabViewController.changeView(uuid: uuid)
    }
}

extension YoruNekoViewController: BrowseHistoryCallback {
    func deleteHistory(by id: UUID) {
        HistoryManager.deleteHistory(uuid: id)
    }
    
    func deleteMultiHistory(IDs: [UUID]) {
        HistoryManager.deleteHistoryList(uuidList: IDs)
    }
    
    func clear() {
        HistoryManager.deleteAll()
    }
}
extension YoruNekoViewController: BookmarkCallBack{
    func addBookmark(_ yrnkBookmark: YRNKBookmark, to parentUUID: UUID){
        BookmarkManager.addBookmark(parentUuid: parentUUID, childPoint: yrnkBookmark)
    }
    
    func addBookmarks(_ yrnkBookmarks:[YRNKBookmark], to parentUUID: UUID){
        BookmarkManager.addBookmarkList(parentUuid: parentUUID, childPointList: yrnkBookmarks)
    }

    func deleteBookmark(to currentUUID: UUID){
        BookmarkManager.deleteBookmark(uuid: currentUUID)
    }
    
    func deleteBookmarks(to currentUUIDList: [UUID]){
        BookmarkManager.deleteBookmarkList(uuidList: currentUUIDList)
    }
    
    func updateBookmark(in uuid: UUID, with bookmark: Bookmark){
        BookmarkManager.updateItemByUuid(uuid: uuid, bookmark: bookmark)
    }
}


extension YoruNekoViewController:ImageViewerCallback{
    
}


